/**
 * src/utils/orderUtils.ts
 * ------------------------------------
 * 订单处理工具
 * 1. OrderUtils：订单创建、状态更新、搜索、统计等核心功能
 * 2. OrderSearchParams：订单搜索参数接口
 * 3. OrderTransactionResult：订单事务处理结果接口
 * 4. 支持订单状态变更的事务处理，确保数据一致性
 * 5. 集成通知系统，订单状态变更时自动发送通知
 * 所有订单相关的业务逻辑都通过此工具类处理
 * 创建日期：2025-08-06
 */
import Taro from '@tarojs/taro'
import { Order, User, OrderStatus, UserRole } from '../types'
import { CloudDataManager } from './cloud'
import { errorUtils, ErrorType } from './errorHandler'
import { notificationUtils } from './notificationUtils'
import { formatDateTime } from './index'

// 订单搜索条件
export interface OrderSearchParams {
  userId?: string;
  status?: OrderStatus | OrderStatus[];
  dateFrom?: Date;
  dateTo?: Date;
  keyword?: string;
  minAmount?: number;
  maxAmount?: number;
}

// 订单状态变更事务结果
interface OrderTransactionResult {
  success: boolean;
  orderId?: string;
  error?: string;
}

// 订单处理工具类
export class OrderUtils {
  /**
   * 创建新订单
   * @param order 订单信息
   * @param user 用户信息
   * @returns Promise<string> 订单ID
   */
  static async createOrder(order: Order, user: User): Promise<string> {
    try {
      // 验证用户权限
      if (!user || !user.id) {
        throw new Error('未登录用户无法创建订单')
      }
      
      // 确保订单属于当前用户
      order.userId = user.id
      order.userName = user.name
      
      // 保存订单到云数据库
      const orderId = await CloudDataManager.saveOrder(order)
      
      // 发送新订单通知给厨师
      await this.sendOrderNotification(orderId, 'new_order', user.id)
      
      // 创建订单状态通知
      await notificationUtils.createOrderStatusNotification(
        { ...order, id: orderId },
        'order_created'
      )
      
      // 显示成功提示
      Taro.showToast({
        title: '订单提交成功',
        icon: 'success'
      })
      
      return orderId
    } catch (error) {
      console.error('创建订单失败:', error)
      Taro.showToast({
        title: '订单提交失败',
        icon: 'error'
      })
      throw error
    }
  }

  /**
   * 更新订单状态 (带事务处理)
   * @param orderId 订单ID
   * @param status 新状态
   * @param user 操作用户
   * @returns Promise<boolean>
   */
  static async updateOrderStatus(orderId: string, status: OrderStatus, user: User): Promise<boolean> {
    try {
      // 验证用户权限
      if (!user || !user.id) {
        throw new Error('未登录用户无法更新订单')
      }
      
      // 获取订单信息
      const orders = await CloudDataManager.getOrders()
      const order = orders.find(o => o.id === orderId)
      
      if (!order) {
        throw new Error('订单不存在')
      }
      
      // 权限检查：只有厨师或订单所有者可以更新订单
      const isChef = user.role === 'chef'
      const isOrderOwner = order.userId === user.id
      
      if (!isChef && !isOrderOwner) {
        throw new Error('无权限更新此订单')
      }
      
      // 状态变更权限检查
      if (status === 'confirmed' || status === 'completed') {
        // 只有厨师可以确认或完成订单
        if (!isChef) {
          throw new Error('只有厨师可以确认或完成订单')
        }
      } else if (status === 'cancelled') {
        // 厨师可以取消任何订单，用户只能取消自己的订单
        if (!isChef && !isOrderOwner) {
          throw new Error('无权限取消此订单')
        }
        
        // 订单确认后，客人不能取消
        if (isOrderOwner && order.status === 'confirmed') {
          throw new Error('订单已确认，无法取消')
        }
      }
      
      // 开始事务处理
      const result = await this.executeOrderStatusTransaction(order, status, user)
      
      if (!result.success) {
        throw new Error(result.error || '订单状态更新失败')
      }
      
      // 显示成功提示
      Taro.showToast({
        title: '订单状态已更新',
        icon: 'success'
      })
      
      return true
    } catch (error) {
      console.error('更新订单状态失败:', error)
      Taro.showToast({
        title: error instanceof Error ? error.message : '更新失败',
        icon: 'error'
      })
      throw error
    }
  }

  /**
   * 执行订单状态变更事务
   * @param order 订单信息
   * @param newStatus 新状态
   * @param user 操作用户
   * @returns Promise<OrderTransactionResult>
   */
  private static async executeOrderStatusTransaction(
    order: Order, 
    newStatus: OrderStatus, 
    user: User
  ): Promise<OrderTransactionResult> {
    try {
      // 1. 准备更新订单状态
      const oldStatus = order.status
      const updatedOrder = {
        ...order,
        status: newStatus,
        updatedAt: new Date()
      }
      
      // 2. 保存订单更新
      await CloudDataManager.saveOrder(updatedOrder)
      
      // 3. 根据状态变更执行额外操作
      let action = ''
      let notificationType: 'order_confirmed' | 'order_completed' | 'order_cancelled' | 'chef_assigned' | null = null
      
      switch (newStatus) {
        case 'confirmed':
          action = 'order_confirmed'
          notificationType = 'order_confirmed'
          
          // 如果有厨师分配，更新厨师信息
          if (updatedOrder.assignedChefId) {
            try {
              // 导入厨师工具类（避免循环依赖）
              const { chefUtils } = await import('./chefUtils')
              await chefUtils.checkAndUpdateChefStatus(updatedOrder.assignedChefId)
            } catch (chefError) {
              console.error('更新厨师状态失败:', chefError)
              // 不中断主流程
            }
          } else {
            // 如果没有分配厨师，尝试自动分配
            try {
              const { chefUtils } = await import('./chefUtils')
              const assignResult = await chefUtils.assignOrderToChef(order.id)
              
              if (assignResult.success && assignResult.chefId) {
                notificationType = 'chef_assigned'
              }
            } catch (assignError) {
              console.error('自动分配厨师失败:', assignError)
              // 不中断主流程
            }
          }
          break
          
        case 'completed':
          action = 'order_completed'
          notificationType = 'order_completed'
          
          // 处理积分奖励
          try {
            // 导入积分工具类（避免循环依赖）
            const { pointsUtils } = await import('./pointsUtils')
            const pointsResult = await pointsUtils.processOrderCompletionPoints(updatedOrder)
            
            if (pointsResult) {
              // 更新订单中的积分信息
              updatedOrder.pointsEarned = pointsUtils.calculateOrderPoints(updatedOrder.finalAmount)
              await CloudDataManager.saveOrder(updatedOrder)
            }
          } catch (pointsError) {
            console.error('处理订单完成积分失败:', pointsError)
            // 不中断主流程
          }
          
          // 如果有厨师分配，更新厨师状态
          if (updatedOrder.assignedChefId) {
            try {
              const { chefUtils } = await import('./chefUtils')
              await chefUtils.checkAndUpdateChefStatus(updatedOrder.assignedChefId)
            } catch (chefError) {
              console.error('更新厨师状态失败:', chefError)
              // 不中断主流程
            }
          }
          break
          
        case 'cancelled':
          action = 'order_cancelled'
          notificationType = 'order_cancelled'
          
          // 如果是从已确认状态取消，且有厨师分配，更新厨师状态
          if (oldStatus === 'confirmed' && updatedOrder.assignedChefId) {
            try {
              const { chefUtils } = await import('./chefUtils')
              await chefUtils.checkAndUpdateChefStatus(updatedOrder.assignedChefId)
            } catch (chefError) {
              console.error('更新厨师状态失败:', chefError)
              // 不中断主流程
            }
          }
          
          // 如果用户已使用积分，返还积分
          if (updatedOrder.pointsUsed && updatedOrder.pointsUsed > 0) {
            try {
              const { pointsUtils } = await import('./pointsUtils')
              await pointsUtils.addPoints(
                updatedOrder.userId,
                updatedOrder.pointsUsed,
                'admin_adjustment',
                `订单取消退还积分: ${updatedOrder.id}`,
                updatedOrder.id
              )
            } catch (pointsError) {
              console.error('退还积分失败:', pointsError)
              // 不中断主流程
            }
          }
          break
          
        default:
          action = 'order_updated'
      }
      
      // 4. 发送状态变更通知
      await this.sendOrderNotification(order.id, action, order.userId)
      
      // 5. 创建用户通知
      if (notificationType && updatedOrder.userId) {
        try {
          await notificationUtils.createOrderStatusNotification(
            updatedOrder,
            notificationType
          )
        } catch (notifyError) {
          console.error('创建通知失败:', notifyError)
          // 不中断主流程
        }
      }
      
      return {
        success: true,
        orderId: order.id
      }
    } catch (error) {
      console.error('订单状态变更事务失败:', error)
      
      // 事务失败，尝试回滚（恢复原状态）
      try {
        const originalOrder = {
          ...order,
          updatedAt: new Date() // 更新时间戳
        }
        await CloudDataManager.saveOrder(originalOrder)
        console.log('订单状态已回滚')
      } catch (rollbackError) {
        console.error('订单状态回滚失败:', rollbackError)
      }
      
      return {
        success: false,
        error: error instanceof Error ? error.message : '订单状态变更失败'
      }
    }
  }

  /**
   * 发送订单通知
   * @param orderId 订单ID
   * @param action 操作类型
   * @param userId 用户ID
   * @returns Promise<any>
   */
  static async sendOrderNotification(orderId: string, action: string, userId: string): Promise<any> {
    try {
      // 使用错误处理工具包装云函数调用
      return await errorUtils.callCloudFunction('orderNotification', {
        orderId,
        action,
        userId
      })
    } catch (error) {
      console.error('发送订单通知失败:', error)
      // 通知失败不影响主流程
      return null
    }
  }

  /**
   * 获取订单统计信息
   * @param orders 订单列表
   * @returns 统计信息
   */
  static getOrderStats(orders: Order[]) {
    const stats = {
      total: orders.length,
      pending: 0,
      confirmed: 0,
      completed: 0,
      cancelled: 0,
      totalAmount: 0
    }
    
    orders.forEach(order => {
      stats[order.status as keyof typeof stats]++
      stats.totalAmount += order.finalAmount
    })
    
    return stats
  }

  /**
   * 获取待处理订单
   * @param orders 订单列表
   * @returns 待处理订单
   */
  static getPendingOrders(orders: Order[]): Order[] {
    return orders.filter(order => 
      order.status === 'pending' || order.status === 'confirmed'
    ).sort((a, b) => 
      new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
    )
  }

  /**
   * 获取用户订单
   * @param orders 订单列表
   * @param userId 用户ID
   * @returns 用户订单
   */
  static getUserOrders(orders: Order[], userId: string): Order[] {
    return orders.filter(order => order.userId === userId)
      .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
  }

  /**
   * 搜索订单
   * @param orders 订单列表
   * @param params 搜索条件
   * @returns 符合条件的订单
   */
  static searchOrders(orders: Order[], params: OrderSearchParams): Order[] {
    return orders.filter(order => {
      // 用户ID筛选
      if (params.userId && order.userId !== params.userId) {
        return false
      }
      
      // 状态筛选
      if (params.status) {
        if (Array.isArray(params.status)) {
          if (!params.status.includes(order.status)) {
            return false
          }
        } else if (order.status !== params.status) {
          return false
        }
      }
      
      // 日期范围筛选
      const orderDate = new Date(order.createdAt).getTime()
      if (params.dateFrom && orderDate < new Date(params.dateFrom).getTime()) {
        return false
      }
      if (params.dateTo && orderDate > new Date(params.dateTo).getTime()) {
        return false
      }
      
      // 金额范围筛选
      if (params.minAmount !== undefined && order.finalAmount < params.minAmount) {
        return false
      }
      if (params.maxAmount !== undefined && order.finalAmount > params.maxAmount) {
        return false
      }
      
      // 关键词搜索
      if (params.keyword) {
        const keyword = params.keyword.toLowerCase()
        const matchesId = order.id.toLowerCase().includes(keyword)
        const matchesUserName = order.userName.toLowerCase().includes(keyword)
        const matchesItems = order.items.some(item => 
          item.dishName.toLowerCase().includes(keyword)
        )
        const matchesNote = order.note ? order.note.toLowerCase().includes(keyword) : false
        
        if (!(matchesId || matchesUserName || matchesItems || matchesNote)) {
          return false
        }
      }
      
      return true
    }).sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
  }

  /**
   * 按日期分组订单
   * @param orders 订单列表
   * @returns 分组后的订单
   */
  static groupOrdersByDate(orders: Order[]): Record<string, Order[]> {
    const grouped: Record<string, Order[]> = {}
    
    orders.forEach(order => {
      const date = new Date(order.createdAt)
      const dateStr = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
      
      if (!grouped[dateStr]) {
        grouped[dateStr] = []
      }
      
      grouped[dateStr].push(order)
    })
    
    return grouped
  }

  /**
   * 格式化订单状态
   * @param status 订单状态
   * @returns 格式化后的状态文本
   */
  static formatOrderStatus(status: OrderStatus): string {
    const statusMap: Record<OrderStatus, string> = {
      pending: '待确认',
      confirmed: '已确认',
      completed: '已完成',
      cancelled: '已取消'
    }
    return statusMap[status]
  }

  /**
   * 获取订单状态颜色
   * @param status 订单状态
   * @returns 状态颜色
   */
  static getOrderStatusColor(status: OrderStatus): string {
    const colorMap: Record<OrderStatus, string> = {
      pending: '#ff9500',
      confirmed: '#007aff',
      completed: '#34c759',
      cancelled: '#ff3b30'
    }
    return colorMap[status]
  }

  /**
   * 导出订单为CSV
   * @param orders 订单列表
   * @returns CSV字符串
   */
  static exportOrdersToCSV(orders: Order[]): string {
    // CSV表头
    const headers = ['订单ID', '用户', '创建时间', '状态', '总金额', '使用积分', '实付金额', '商品详情']
    
    // 转换订单数据为CSV行
    const rows = orders.map(order => {
      const status = this.formatOrderStatus(order.status)
      const createdAt = formatDateTime(order.createdAt)
      const items = order.items.map(item => `${item.dishName}(${item.quantity}份)`).join('; ')
      
      return [
        order.id,
        order.userName,
        createdAt,
        status,
        order.totalAmount.toFixed(2),
        order.pointsUsed,
        order.finalAmount.toFixed(2),
        items
      ]
    })
    
    // 合并表头和行
    const csvContent = [
      headers.join(','),
      ...rows.map(row => row.join(','))
    ].join('\n')
    
    return csvContent
  }
}

// 导出工具函数
export const orderUtils = {
  createOrder: OrderUtils.createOrder,
  updateOrderStatus: OrderUtils.updateOrderStatus,
  sendOrderNotification: OrderUtils.sendOrderNotification,
  getOrderStats: OrderUtils.getOrderStats,
  getPendingOrders: OrderUtils.getPendingOrders,
  getUserOrders: OrderUtils.getUserOrders,
  searchOrders: OrderUtils.searchOrders,
  groupOrdersByDate: OrderUtils.groupOrdersByDate,
  formatOrderStatus: OrderUtils.formatOrderStatus,
  getOrderStatusColor: OrderUtils.getOrderStatusColor,
  exportOrdersToCSV: OrderUtils.exportOrdersToCSV
} 